// wglshader.cpp
//

#include "config.h"
#include "wgl/wglshader.hpp"
#include "wgl/wglutils.hpp"
#include "wgl/wgl_gl.hpp"

using namespace wgl;



// Shader::Shader
//
Shader::Shader ( GLenum type,
                 const std::string &path )
  : type(type),
    path(path)
{
}



// Shader::~Shader
//
Shader::~Shader ()
{
}



// Shader::compile
//
bool Shader::compile ()
{
  if (compiled)
    {
      GLint status;
      gl.GetShaderiv(id, GL_COMPILE_STATUS, &status);
      return status ? true : false;
    }
  
  WGL_TRACE("loading shader %s", path.c_str());
  std::vector<char> source = wgl::utils::read_file(path);
  source.push_back(0);

  // WGL_TRACE("source:\n%s", source.data());
  
  if (id == 0)
    id = gl.CreateShader(type);

  const char *str = source.data();
  gl.ShaderSource(id, 1, &str, NULL);

  WGL_TRACE("compiling shader (%lu bytes)", WGL_LU(source.size()));
  gl.CompileShader(id);

  GLint log_len, real_len;
  gl.GetShaderiv(id, GL_INFO_LOG_LENGTH, &log_len);
  GLchar log[std::min(log_len, 1)];
  if (log_len != 0)
    gl.GetShaderInfoLog(id, log_len, &real_len, log);

  GLint status;
  gl.GetShaderiv(id, GL_COMPILE_STATUS, &status);
  if (status)
    {
      WGL_TRACE("compilation ok");
      if (log_len != 0)
        WGL_WARNING("got logs:\n%s", log);
      return true;
    }
  else
    {
      WGL_ERROR("shader compilation failed");
      GLint log_len, real_len;
      gl.GetShaderiv(id, GL_INFO_LOG_LENGTH, &log_len);
      GLchar log[log_len];
      gl.GetShaderInfoLog(id, log_len, &real_len, log);
      WGL_ERROR("compilation logs:\n%s:%s", path.c_str(), log);
      WGL_FATAL("stop");
      return false;
    }
}
